#include "apfsds_config.h"

static tstack_t apdstinfo_tlsstk;
static TLS_INITIAL apdstls_t *apdstinfo_tls;
DEF_APDSTINFO_TLS(&apdstinfo_tlsstk, &apdstinfo_tls, malloc, APFSDS_COREID_UPDFREQ, mp_coreid)

static TLS_INITIAL spobj_t *lknode_tls;
DEF_LOCKNODE_SPSLAB(splknode, &lknode_tls, HDEF_CACHE_LINE_BYTES, SPLK_POOL_SIZE)

DEF_NLOCK(mcs, mcs, OUFUN_OF(spinyield_wait), OUFUN_OF(spslablknode))
DEF_NLOCK(mcs, bounded_mcs, OUFUN_OF(spin_wait_bounded), OUFUN_OF(spslablknode))
DEF_NLOCK(mcs, futex_mcs, OUFUN_OF(futex_wait), OUFUN_OF(spslablknode))
DEF_NLOCK(mcs, yield_mcs, OUFUN_OF(schedyield_wait), OUFUN_OF(spslablknode))

static TLS_INITIAL apdsfuture_t apdsfuture_tls[LOCK_MAXFUTURES]; 
static TLS_INITIAL hword_t apdsfuture_cnt; 
static TLS_INITIAL slist_t *apdsfuture_head;
SAI apdsfuture_t *apfsdsfuture_get_tls(){
	if (!apdsfuture_head){
		ASSERT(apdsfuture_cnt < LOCK_MAXFUTURES);
		return &apdsfuture_tls[apdsfuture_cnt++];
	}
	slist_t *ret = apdsfuture_head;
	apdsfuture_head = ret->next;
	return (apdsfuture_t *)ret;
}
SAI void apfsdsfuture_ret_tls(apdsfuture_t *future){
	slist_t *node = (slist_t *)future;
	node->next = apdsfuture_head;
	apdsfuture_head = node;
}
/* 用ptls alloc和free来解决 */
LOCKS2APDS(mcs, apdsmcs, apfsdsfuture_get_tls, apfsdsfuture_ret_tls)


APDS2APFSDS(apdsmcs, (OUFUN_OF(alignlknode))->get_lknode,  (OUFUN_OF(alignlknode))->ret_lknode)

/* 初始化 */
#include <pthreadalt/pthreadalt_init.h>
DEF_PTHREADALT_INIT
DEF_SYSINIT(apdstls)
DEF_CFLOWINIT(apdstls)
DEF_CFLOWFIN(apdstls, splknode)
DEF_SYSFIN(__omega)
